
#ifndef MY_LIST_H
#define MY_LIST_H


#include <Arduino.h>
#include <functional> // 引入std::function以支持回调函数
 
template <typename T>
class List {
private:
    struct Node {
        T data;
        Node* next;
        Node(T val) : data(val), next(nullptr) {}
    };
 
    Node* head;
    Node* tail;
    size_t size;
 
public:
    List() : head(nullptr), tail(nullptr), size(0) {}
 
    ~List() {
        clear();
    }
 
    void add(T value) {
        Node* newNode = new Node(value);
        if (tail!=nullptr) {
            tail->next = newNode;
        } else {
            head = newNode;
        }
        tail = newNode;
        size++;
    }
 
    void remove(T value) {
        Node* current = head;
        Node* previous = nullptr;
 
        while (current && current->data != value) {
            previous = current;
            current = current->next;
        }
 
        if (current) {
            if (previous) {
                previous->next = current->next;
            } else {
                head = current->next;
            }
 
            if (current == tail) {
                tail = previous;
            }
            if(current!=nullptr){
                delete current;
            }
           
            size--;
        }
    }
 
    void clear() {
        Node* current = head;
        while (current) {
            Node* temp = current;
            current = current->next;
            if(temp!=nullptr){
                delete temp;
            }
           
        }
        head = tail = nullptr;
        size = 0;
    }
 
    bool isEmpty() const {
        return size == 0;
    }
 
    size_t getSize() const {
        return size;
    }
    // 新的遍历函数，接受一个回调函数
    void forEach(std::function<void(  T&)> callback) const {
        Node* current = head;
        while (current) {
            callback(current->data);
            current = current->next;
        }
    }

        // 如果不希望使用std::function（例如在Arduino上），可以使用函数指针，但牺牲了一些灵活性
    // 注意：函数指针方法要求回调函数具有特定的签名，并且不能捕获任何状态（即不能是lambda或闭包）
    // typedef void (*CallbackFunc)(const T&);
    // void forEach(CallbackFunc callback) const {
    //     Node* current = head;
    //     while (current) {
    //         callback(current->data);
    //         current = current->next;
    //     }
    // }
 
    void printList() const {
        Node* current = head;
        while (current) {
            Serial.print("->");
            if (current->next) {
                Serial.print(" -> ");
            }
            current = current->next;
        }
        Serial.println(",,,,,");
    }
};

#endif